package com.babel.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;

import org.apache.commons.lang.StringUtils;

/**
 * 数字工具类
 * 
 * @author tangzhi
 */
public class CalculateUtil {

	/**
	 * double 相加 HALF_EVEN
	 * 
	 * @param scale
	 * @param dd
	 * @return
	 */
	public static double doubleAdd(int scale, double... dd) {
		BigDecimal result = BigDecimal.ZERO;
		for (double n : dd) {
			result = result.add(new BigDecimal(Double.toString(n)));
		}
		return result.setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
	}

	public static BigDecimal double2BigDecimal(int scale, double dd) {
		BigDecimal result = BigDecimal.ZERO;
		result = result.add(new BigDecimal(Double.toString(dd)));
		return result.setScale(scale, RoundingMode.HALF_EVEN);
	}

	/**
	 * double 相加
	 * 
	 * @param dd
	 * @return
	 */
	public static double doubleAdd(double... dd) {
		BigDecimal result = BigDecimal.ZERO;
		for (double n : dd) {
			result = result.add(new BigDecimal(Double.toString(n)));
		}
		return result.doubleValue();
	}

	public static double parseString2Double(String str, int scale) {
		BigDecimal result = BigDecimal.ZERO;
		BigDecimal value = new BigDecimal(str);
		result = result.add(value);
		return result.setScale(scale).doubleValue();
	}

	public static double doubleAbs(double d, int scale) {
		BigDecimal result = BigDecimal.ZERO;
		if (d < 0.0) {
			d = -d;
		}
		result = result.add(new BigDecimal(d));
		return result.setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
	}

	/**
	 * double 相加
	 * 
	 * @param scale
	 * @param mode
	 * @param dd
	 * @return
	 */
	public static double doubleAdd(int scale, RoundingMode mode, double... dd) {
		BigDecimal result = BigDecimal.ZERO;
		for (double n : dd) {
			result = result.add(new BigDecimal(Double.toString(n)));
		}
		return result.setScale(scale, mode).doubleValue();
	}

	/**
	 * double相加
	 * 
	 * @param d1
	 * @param d2
	 * @return
	 */
	public static double doubleAdd(double d1, double d2) {
		BigDecimal bd1 = new BigDecimal(Double.toString(d1));
		BigDecimal bd2 = new BigDecimal(Double.toString(d2));
		return bd1.add(bd2).doubleValue();

	}

	/**
	 * 相加 取位 d1+d2 n.scale HALF_EVEN
	 * 
	 * @param d1
	 * @param d2
	 * @param scale
	 * @return
	 */
	public static double doubleAdd(double d1, double d2, int scale) {
		BigDecimal bd1 = new BigDecimal(Double.toString(d1));
		BigDecimal bd2 = new BigDecimal(Double.toString(d2));
		return bd1.add(bd2).setScale(scale, RoundingMode.HALF_EVEN)
				.doubleValue();

	}

	/**
	 * 相加 取位 d1+d2 n.scale
	 * 
	 * @param d1
	 * @param d2
	 * @param scale
	 * @param mode
	 * @return
	 */
	public static double doubleAdd(double d1, double d2, int scale,
			RoundingMode mode) {
		BigDecimal bd1 = new BigDecimal(Double.toString(d1));
		BigDecimal bd2 = new BigDecimal(Double.toString(d2));
		return bd1.add(bd2).setScale(scale, mode).doubleValue();

	}

	/**
	 * double 相减
	 * 
	 * @param d1
	 * @param d2
	 * @return
	 */
	public static double doubleSubtract(double d1, double d2) {
		return new BigDecimal(Double.toString(d1)).subtract(
				new BigDecimal(Double.toString(d2))).doubleValue();
	}

	/**
	 * double 相减
	 * 
	 * @param d1
	 * @param d2
	 * @param scale
	 * @return
	 */
	public static double doubleSubtract(double d1, double d2, int scale) {
		BigDecimal b = new BigDecimal(Double.toString(d1))
				.subtract(new BigDecimal(Double.toString(d2)));
		return b.setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
	}

	/**
	 * double 相减
	 * 
	 * @param d1
	 * @param d2
	 * @param scale
	 * @param mode
	 * @return
	 */
	public static double doubleSubtract(double d1, double d2, int scale,
			RoundingMode mode) {
		BigDecimal b = new BigDecimal(Double.toString(d1))
				.subtract(new BigDecimal(Double.toString(d2)));
		return b.setScale(scale, mode).doubleValue();
	}

	public static double doubleSubtract(double d1, int scale, double... d2) {
		BigDecimal b = new BigDecimal(Double.toString(d1));
		for (int i = 0; i < d2.length; i++) {
			double d = d2[i];
			b.subtract(new BigDecimal(d));
		}
		return b.setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
	}

	/**
	 * 格式化数字
	 * 
	 * @param d1
	 * @param scale
	 * @return
	 */
	public static double formatNubmer(double d1, int scale) {
		BigDecimal bd = new BigDecimal(Double.toString(d1));
		return bd.setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
	}

	/**
	 * 格式化数字 含取舍条件
	 * 
	 * @param d
	 * @param mode
	 * @param d1
	 * @return
	 */
	public static double formatNubmer(double d1, int scale, RoundingMode mode) {
		BigDecimal bd = new BigDecimal(Double.toString(d1));
		return bd.setScale(scale, mode).doubleValue();
	}

	/**
	 * 格式化数字
	 * 
	 * @param d1
	 * @param scale
	 * @param formatter
	 * @return
	 */
	public static String formatNubmer(double d1, int scale, String formatter) {
		BigDecimal bd = new BigDecimal(Double.toString(d1));
		double dd = bd.setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
		DecimalFormat df = new DecimalFormat(formatter);
		return df.format(dd);
	}

	/**
	 * 格式化数字
	 * 
	 * @param d1
	 * @param scale
	 * @param mode
	 * @param formatter
	 * @return
	 */
	public static String formatNubmer(double d1, int scale, RoundingMode mode,
			String formatter) {
		BigDecimal bd = new BigDecimal(Double.toString(d1));
		double dd = bd.setScale(scale, mode).doubleValue();
		DecimalFormat df = new DecimalFormat(formatter);
		return df.format(dd);
	}

	/**
	 * 货币形式格式字符串
	 * 
	 * @param ####,###0.00
	 * @param value
	 */
	public static String formatNumberWithString(String formatter, String value) {
		if (StringUtils.isEmpty(value) || "null".equals(value)) {
			return "0.00";
		}
		if (StringUtils.isEmpty(formatter)) {
			formatter = "#,##0.00#";
		}
		BigDecimal bd = new BigDecimal(value);
		DecimalFormat df = new DecimalFormat(formatter);
		String result = df.format(bd);
		return result;
	}

	/**
	 * 相除
	 * 
	 * @param d1
	 * @param d2
	 * @return
	 */
	public static double doubleDivide(double d1, double d2) {
		BigDecimal bd1 = new BigDecimal(Double.toString(d1));
		BigDecimal bd2 = new BigDecimal(Double.toString(d2));
		return bd1.divide(bd2).doubleValue();
	}

	/**
	 * 相除 取位 d1/d2 n.scale HALF_EVEN
	 * 
	 * @param d1
	 * @param d2
	 * @param scale
	 * @return
	 */
	public static double doubleDivide(double d1, double d2, int scale) {
		BigDecimal bd1 = new BigDecimal(Double.toString(d1));
		BigDecimal bd2 = new BigDecimal(Double.toString(d2));
		BigDecimal bd3 = bd1.divide(bd2, 10, RoundingMode.HALF_EVEN);
		return bd3.setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
	}

	/**
	 * 相除 取位 d1/d2 n.scale
	 * 
	 * @param d1
	 * @param d2
	 * @param scale
	 * @param mode
	 * @return
	 */
	public static double doubleDivide(double d1, double d2, int scale,
			RoundingMode mode) {
		BigDecimal bd1 = new BigDecimal(Double.toString(d1));
		BigDecimal bd2 = new BigDecimal(Double.toString(d2));
		BigDecimal bd3 = bd1.divide(bd2, 10, mode);
		return bd3.setScale(scale, mode).doubleValue();
	}

	/**
	 * 相乘
	 * 
	 * @param d1
	 * @param d2
	 * @return
	 */
	public static double doubleMultiply(double d1, double d2) {
		BigDecimal bd1 = new BigDecimal(Double.toString(d1));
		BigDecimal bd2 = new BigDecimal(Double.toString(d2));
		return bd1.multiply(bd2).doubleValue();
	}

	/**
	 * 相乘 取位 d1*d2 n.scale HALF_EVEN
	 * 
	 * @param d1
	 * @param d2
	 * @param scale
	 * @return
	 */
	public static double doubleMultiply(double d1, double d2, int scale) {
		BigDecimal bd1 = new BigDecimal(Double.toString(d1));
		BigDecimal bd2 = new BigDecimal(Double.toString(d2));
		return bd1.multiply(bd2).setScale(scale, RoundingMode.HALF_EVEN)
				.doubleValue();
	}

	public static long double2Long(double d) {
		BigDecimal bd1 = new BigDecimal(Double.toString(d));
		return bd1.setScale(0, RoundingMode.HALF_EVEN).longValue();
	}

	/**
	 * 相乘 取位 d1*d2 n.scale
	 * 
	 * @param d1
	 * @param d2
	 * @param scale
	 * @param mode
	 * @return
	 */
	public static double doubleMultiply(double d1, double d2, int scale,
			RoundingMode mode) {
		BigDecimal bd1 = new BigDecimal(Double.toString(d1));
		BigDecimal bd2 = new BigDecimal(Double.toString(d2));
		return bd1.multiply(bd2).setScale(scale, mode).doubleValue();
	}

	/**
	 * 将整数转化为四位数字
	 * 
	 * @param number
	 * @return
	 */
	public static String formatFourNumber(int number) {
		NumberFormat nf = new DecimalFormat("0000");
		return nf.format(number);
	}

	public static boolean isDivisible(double d1, double d2) {
		return d1 % d2 == 0.0 ? true : false;
	}

	/**
	 * 页面展示保留两位小数的精度数字
	 * 
	 * @param num
	 * @return
	 */
	public static String scaleNumber(double num) {
		BigDecimal decimal = new BigDecimal(num).setScale(2,
				BigDecimal.ROUND_HALF_UP);
		return decimal.toString();
	}

	public static String getIntValue(double num) {
		BigDecimal decimal = new BigDecimal(num).setScale(0,
				BigDecimal.ROUND_HALF_UP);
		return decimal.intValue() + "";
	}

	public static double doublePower(double num, int power, int scale) {
		BigDecimal decimal = new BigDecimal(num);
		decimal = decimal.pow(power);
		return decimal.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}
}